thumbnail
고급 캐시 전략
Frontend
2023.05.01.

썸네일: UnsplashPaul Hanaoka

출처 : 웹 성능 최적화 기법


웹 성능 최적화 기법(루비페이퍼 사) 도서에 대한 핵심 내용과 지식을 정리한 포스트입니다. 포스트에 올라오는 내용은 도서의 일부이기 때문에 더 자세한 내용이 궁금하신 분들은 출처에서 도서를 구매해 읽어보시는 것을 추천드립니다.


6.3 캐시 최적화 방안

  • 캐시 사용 최대화 3가지 기본 원리
    1. 최대한 많이 캐시하라
    2. 최대한 오래 캐시하라
    3. 최대한 가까이 캐시하라

6.3.1 캐시 가능한 콘텐츠 구분하기

  • 어떤 콘텐츠를 캐시할 수 있는지, 캐시하면 안되는 지를 알아야하며, 캐시 가능한 리소스를 최대한 찾아내 서비스할 필요가 있다.
  • WebPageTest를 통해 웹 페이지 구성이 어떻게 되고, 얼마나 많은 파일들을 캐시할 수 있는지 확인할 수 있다.
  • 웹 사이트 내 콘텐츠는 정적 콘텐츠와 동적 콘텐츠로 구분할 수 있다.
    • 정적 콘텐츠 : URL을 호출할 때마다 변함없이 같은 응답을 주는 콘텐츠로 이미지, CSS, 자바스크립트 등
    • 동적 콘텐츠 : 사용자 요청시마다 서버에 의해 다시 생성, 응답되는 콘텐츠로 서버에서는 HTTP 요청과 함께 입력 시간을 포함한 다양한 변숫값에 따라 콘텐츠를 동적으로 생성하여 응답
  • 캐시하기 어려운 콘텐츠
    • 개인화된 콘텐츠
    • API 호출이나 Ajax 요청에 대한 콘텐츠
    • Beacon 전달 또는 쿠키 설정을 위한 호출

6.3.2 올바른 캐시 정책 설정하기

1. 캐시할 수 있는 콘텐츠인지 판단하기

  • 일반적으로 정적 콘텐츠들이 캐시 가능한 페이지로 분류될 수 있지만 모든 정적 콘텐츠를 캐시할 수는 없다. (보안에 민감한 내용 등)
  • 캐시할 수 없는 콘텐츠의 경우 응답 헤더에 Cache-Control : no-store를 설정한다.

2. 캐시할 수 있는 콘텐츠들은 매번 원본 서버에 변경 사항을 확인해야 하는지 판단

  • 정적이지만 자주 변하는 콘텐츠들의 경우 변경시 캐시에 바로 업데이트 할 필요가 있다.
  • 변경에 민감한 콘텐츠를 응답 헤더에 Cache-Control: no-cache 혹은 Cache-Control: max-age=0을 설정한다.

3. 캐시할 콘텐츠 성격 판단

  • 모든 사용자 공통 콘텐츠는 Cache-Control:public, 개인화된 콘텐츠는 Cache-Control:private 사용

4. 캐시 주기 설정 및 max-age 추가

6.3.3 캐시 주기 결정하기

  • 캐시 주기는 가능한한 오래하는 것이 좋다. 캐시 주기가 길수록 사용자 요청이 캐시에서 처리되어 서버까지의 트래픽을 많이 감소시킬 수 있기 때문
  • 캐시 주기가 짧으면 원본 파일 변경이 캐시에 빠르게 반영된다는 장점이 있다.

1. 캐시 주기는 콘텐츠 타입별로 다르게 설정 가능

  • 이미지, 동영상 등 미디어 파일 등은 쉽게 변경되지 않으며, 미디어 파일은 링크가 바뀌면 자연스럽게 새로운 파일을 불러와 캐시하므로 내용 변경 필요없이 링크만 바꾸면 된다.
  • 특별한 이유가 없다면 캐시 주기를 1년 정도로 길게 설정하는 것이 좋다.

2. 링크 변경 없이 이미지 내용만 바꿔야 한다면 캐시 무효화(Invalidation) 방식으로 해당 이미지만 캐시에 업데이트한다.

  • 이미지, 미디어 파일을 제외한 웹 리소스 파일들은 변경 주기에 따라 다르게 설정하며 범위에서 가능한 길게 설정한다.
  • 폰트 파일은 캐시 주기를 길게, 스타일 시트 등은 상대적으로 짧게 설정한다.
  • 아예 캐시를 안하는 것보다는 짧게라도 캐시 주기를 정해서 캐시하는 것이 성능에 유리

3. 모든 정적 파일에 대해 캐시 주기를 길게 설정하거나 수동으로 캐시 주기를 관리할 수도 있다.

  • 수동으로 캐시 주기를 관리하는 방법 2가지
  1. 파일명 뒤에 해시값을 자동으로 붙여 파일명을 변경하는 방법
  2. 파일 요청 시에 쿼리 스트링으로 버전을 지정하는 방법

6.3.4 캐시에 적합한 디렉터리 구조 구성하기

1. 캐시할 수 있는 콘텐츠를 별도의 폴더에 분류해 관리한다.

  • 정적 콘텐츠들을 /static 디렉터리로 관리하는 방법 등

2. 캐시 주기별로 나누어 구성한다.

  • 주기별로 디렉터리를 나누어 관리하기

3. 동일한 파일을 여러 곳에 분산시키지 않는다.

6.3.5 캐시 키 올바르게 사용하기

  • 캐시 키란, 캐시 서버가 원본의 복사본을 저장하고 빠르게 조회하기 위해 사용하는 키 값을 말한다.
일반적인 캐시 키 구성
호스트/패스? 쿼리 스트링
www.foekorea.com/kr/feo/optimization/myPic.jpg?width=200&height=100

캐시 키들은 서로 다른 객체를 참조한다
www.foekorea.com/kr/feo/optimization/myPic.jpg
www.foekorea.com/jp/feo/optimization/myPic.jpg
www.foekorea.com/jp/feo/optimization/myPic.jpg?width=200

캐시 오염과 캐시 충돌

  • 캐시 오염: 원본 서버에 하나의 원본 파일만 존재하는데 캐시에 복사본이 여러 개 존재하는 것
  • 캐시 충돌 : 요청 URL이 하나인데 브라우저 환경에 따라 서버에서 제공하는 응답이 달라져 최초 요청한 브라우저의 응답만 캐시되는 것

캐시 오염 제거

  • 캐시 오염은 최종 사용자에게 영향을 주지는 않지만 캐시 서버의 효율성에 큰 영향을 미칠 수 있으며, 캐시가 퍼지면 트래픽 부담을 줄 수 있다.
  1. URL에 특정 쿼리 스트링 값이 달라지더라도 응답이 항상 같다면 캐시 키에서 쿼리 스트링 무시하도록 설정
  2. 쿼리 스트링 순서를 동일하게 정렬
  3. Vary 헤더 사용

캐시 충돌 방지

  • 동적 페이지를 캐시할 때 주로 발생하며, 일반적인 홈페이지는 로그인 전후로 같은 URL을 사용하기 때문에 동적 페이지에 대한 특별한 캐시 설정을 하지 않으면 캐시 충돌 현상이 나타난다.
  • 캐시 충돌을 피하려면 기본적으로 동적 페이지에는 캐시를 적용하지 않아야 하며, 일부 동적 페이지에 캐시를 사용하고자 한다면 Cache-Control:private로 브라우저에만 캐시하여 페이지 로딩 시간을 단축할 수 있다.

6.3.6 CDN 사용하기

  • 캐시 효율화를 위한 3원칙 중 사용자에게 가깝게 캐시하라는 내용에 해당
  • 글로벌 서비스를 운용중이라면, CDN을 사용하여 세계 여러 지역 데이터 센터들에 리버스 프록시 캐시 서버를 두고 필요한 정적 콘텐츠들을 저장해놓을 수 있다.

6.4 동적 콘텐츠 캐시

  • 특성에 따른 웹 콘텐츠 분류

1. 정적 콘텐츠와 동적 콘텐츠

  • 정적 콘텐츠
    • 한번 생성되어 좀처럼 변하지 않는 콘텐츠
    • 이미지, 동영상, CSS, 자바스크립트 등
  • 동적 콘텐츠
    • 사용자 요청에 따라 서버가 바로 생성하는 콘텐츠
    • 장바구니, 주식 시세,
    • JSON, XML, HTML 형태 데이터

2. 익명(anonymous) 콘텐츠와 개인화(personalized) 콘텐츠

  • 익명 콘텐츠 : 누구에게나 드러나는 콘텐츠
  • 개인화 콘텐츠 : 사용자 정보에 따라 다르게 나타나는 콘텐츠

3. 시간에 민감한 콘텐츠와 시간에 둔감한 콘텐츠

6.4.1 동적 콘텐츠 캐시

  • 원본 서버가 동적 콘텐츠를 사용자에게 전달하는 방법
    1. 동적 정보를 쿠키에 넣어 보낸다.
    2. Ajax 요청으로 관련 정보를 동적으로 받아온다.
  • 요청 쿠키, 헤더 혹은 쿼리 스트링에 동적 콘텐츠에 대한 정보가 있으면, 이 정보들을 캐시 키에 추가하여 동적 콘텐츠를 캐시할 수 있다.

주의점

  1. 보안에 주의해야 한다.
  • 개인화 콘텐츠에는 사생활을 침해하는 개인 정보가 포함되어 있을 수 있다.
  1. 캐시 서버 용량에 유의해야 한다.
  • 캐시 서버 용량이 소진되면 CPU 사용량이 늘어나 캐시 효율이 떨어지므로 과도한 개인 콘텐츠 캐시는 지양한다.

6.4.2 POST 응답 캐시

  • POST 메서드는 HTTP 페이로드 메시지에 쿼리 스트링을 포함시켜 보낼 때 사용한다
  • GET메소드는 쿼리 스트링 길이에 제한이 있지만, POST 메서드는 HTTP 헤더에 쿼리 스트링 내용을 포함해 보내므로 데이터 크기에 제한이 없으며, 보안 측면에서도 상대적으로 안전하다.
  • POST 메서드의 응답 내용이 안전한 내용이라면 캐시할 수 있으며, 이때 MD5 같은 해시 알고리즘을 이용해 암호화해야 한다.

6.5 고급 캐시 전략

6.5.1 Edge Side Include

  • 웹 페이지의 첫 번째 HTML이 서버에서 브라우저까지 도달하는 시간을 Time To First Byte라고 하며, 웹 사이트를 측정하는 중요 지표가 된다.
  • 그러나 많은 웹 관리자들은 동적인 콘텐츠가 존재하기 때문에 첫 번째 HTML을 캐시하지 않는데, 동적 부분만 따로 떼어 별도로 수행시킨 후 캐시된 나머지와 다시 조합하면 로딩 성능이 개선될 수 있다.
    • 특히 CDN 에지 서버에 캐시되어 있으면 개선 폭이 더 커진다.

ESI

  • ESI는 인터넷 에지에서 웹 페이지 조각을 동적으로 조합, 조립, 전달할 수 있도록 이에 대한 문법과 용도를 정의한 XML 기반 표준 마크업 언어이다.
  • ESI를 사용하면 한 페이지 안에 다른 페이지를 포함시킬 수 있으며, 각 페이지들이 독립 객체로 취급되어 각 다른 캐시 정책을 사용할 수 있다.
  • ESI는 HTML 같은 마크업 언어이며 문법이 단순해 쉽게 배우고 빠르게 사용할 수 있다.
  • ESI 언어를 지원하는 대표적인 오픈 소스 웹 캐시는 Varnish, Squid 등이 있고, Oracle, IBM 등 중요 기업형 소프트웨어 업체에서 판매하는 상용 웹 캐시도 ESI를 지원한다.

ESI 사용 용도

  1. 페이지 내에 일부 동적인 부분이 존재할 때, 이 부분만 별도로 만들어 본래 페이지에 동적으로 삽입
  2. 서로 다른 성격 콘텐츠를 각 캐시 정책을 사용해 캐시하고자 할 때
  3. 사용자 등급에 따라 콘텐츠를 제한하고자 할 때
  4. 웹 애플리케이션 개발에 협업이 필요할 때

6.5.2 HTML5 로컬 스토리지

  • HTML5는 Web Hypertext Application Technology Working Group(WHATWG)에서 작업한 표준으로 2014년 W3C를 통해 발표됨
  • HTML5의 가장 큰 장점 중 하나는 HTML5만의 다양한 기능을 API를 사용할 수 있도록 되어 웹 페이지 자체가 일종의 웹/모바일 어플리케이션으로 구동될 수 있게된 점이다.

HTML5 주요 기능

  • WeSemantic Tag: Semantic을 표준 Tag로 정의해 사용하여 머신 간 가독성 및 사용자 접근성 향상
  • Web Storage : API를 통해 세션 스토리지, 로컬 스토리지 IndexedDB 사용가능하며, 오프라인 상태에서 웹페이지 로딩 가능
  • Multimedia : 플러그인 없이 오디오와 비디오 재생 가능
  • Graphics : SVG, Canvas, WebGL, CSS 3D 등 확대외어 플러그인 없이 화려한 그래픽 표현
  • Device Access : 기기의 마이크로폰, 카메라, 연락처, 이벤트 등에 네이티브 앱처럼 접근 가능
  • Performance : Web Worker를 도입해 백그라운드 프로세싱 기능과 멀티스레드 사용하여 속도 향상
  • Connectivity : Web Socket을 사용해 클라이언트 서버 간 TCP 통신 가능 (실시간 메시징, 푸시 알림 구현)
  • CSS3 지원

웹 스토리지

  • 사용자 주요 정보, 웹 리소스들을 브라우저 로컬 저장소에 저장하여 재사용이 가능
  • 최소 5MB 크기
  • 쿠키를 대체하여 네트워크 대역폭 낭비를 절약하는 용도로 사용
  • 세션이 살아있을 동안만 저장되는 세션 스토리지, 영원히 저장되는 로컬 스토리지로 구분

© 2022 Developer Abel, Powered By Gatsby.